package com.yunhe.authority.service.wechat.impl;

import com.yunhe.authority.domain.authority.Menu;
import com.yunhe.authority.domain.wechat.KingKongDistrictDTO;
import com.yunhe.authority.repository.authority.MenuRepository;
import com.yunhe.authority.repository.wechat.KingKongDistrictRepository;
import com.yunhe.authority.service.wechat.KingKongDistrictService;
import com.yunhe.common.exception.ArgumentErrorException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
 * @author zhengbo
 * @date 2021/10/19 15:01
 */
@Service
public class KingKongDistrictServiceImpl implements KingKongDistrictService {

    @Autowired
    private KingKongDistrictRepository kingKongDistrictRepository;

    @Autowired
    private MenuRepository menuRepository;

    @Override
    @Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
    public void saveKingKongDistrict(String ids, Long parkId, String usePlatform) throws ArgumentErrorException {
        if (null == parkId || StringUtils.isEmpty(usePlatform)) {
            throw new ArgumentErrorException("请选择平台和园区");
        }
        //先解绑再绑定
        kingKongDistrictRepository.unbindKingKongDistrict(parkId, usePlatform);
        //需要放到金刚区的菜单 绑定园区 增加关系
        if (StringUtils.isNotEmpty(ids)) {
            String[] menuIds = ids.split(",");
            for (int i = menuIds.length - 1; i >= 0; i--) {
                kingKongDistrictRepository.bindKingKongDistrict(Long.valueOf(menuIds[i]), parkId, usePlatform, (long) i);
            }
        }
    }

    @Override
    public KingKongDistrictDTO findKingKongDistrictMenuByParkId(Long parkId, String usePlatform) {
        String wechat = "1";
        String app = "2";
        KingKongDistrictDTO kingKongDistrictDTO = new KingKongDistrictDTO();

        List<Menu> kingKongDistrictList = kingKongDistrictRepository.findKingKongDistrictMenuByParkId(parkId, usePlatform);
        setChildren(kingKongDistrictList);
        kingKongDistrictDTO.setKingKongDistrictList(kingKongDistrictList);

        List<Menu> parkAllMenuList = new ArrayList<>();
        if (wechat.equals(usePlatform)) {
            parkAllMenuList = (List<Menu>)menuRepository.findMenusByStationIdAndSystemMenuCategory(parkId, "3");
        }
        if (app.equals(usePlatform)) {
            parkAllMenuList = (List<Menu>)menuRepository.findMenusByStationIdAndSystemMenuCategory(parkId, "2");
        }
        setChildren(parkAllMenuList);
        kingKongDistrictDTO.setParkAllMenuList(parkAllMenuList);

        return kingKongDistrictDTO;
    }

    @Override
    public List<Menu> findKingKongDistrictMenuByRoleIdAndParkId(String roleIds, Long parkId, String usePlatform) {
        List<Menu> menuList = new ArrayList<>();
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdsSplit = roleIds.split(",");
            for (String roleId : roleIdsSplit) {
                List<Menu> menus = kingKongDistrictRepository.findKingKongDistrictMenuByRoleIdAndParkId(Long.valueOf(roleId), parkId, usePlatform);
                menuList = takeUnion(menuList, menus);
            }
        }
        return setChildren(menuList);
    }

    @Override
    public List<Menu> findKingKongDistrictMenuByRoleIdAndCompanyIdAndParkId(String roleIds, Long parkId, Long companyId, String usePlatform) {
        List<Menu> menuList = new ArrayList<>();
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdsSplit = roleIds.split(",");
            for (String roleId : roleIdsSplit) {
                List<Menu> menus = kingKongDistrictRepository
                        .findKingKongDistrictMenuByRoleIdAndCompanyIdAndParkId(Long.valueOf(roleId), parkId, companyId, usePlatform);
                menuList = takeUnion(menuList, menus);
            }
        }
        return setChildren(menuList);
    }

    @Override
    public List<Menu> findDistrictMenuByRoleIdAndCompanyIdAndParkId(String roleIds, Long parkId, Long companyId, String usePlatform) {
        List<Menu> menuList = new ArrayList<>();
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdsSplit = roleIds.split(",");
            for (String roleId : roleIdsSplit) {
                List<Menu> menus = kingKongDistrictRepository
                        .findDistrictMenuByRoleIdAndCompanyIdAndParkId(Long.valueOf(roleId), parkId, companyId, "3");
                menuList = takeUnion(menuList, menus);
            }
        }
        return setChildren(menuList);
    }

    @Override
    public List<Menu> findAppMenuMoreByParkId(String roleIds, Long parkId, String usePlatform) {
        List<Menu> menuList = new ArrayList<>();
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdsSplit = roleIds.split(",");
            for (String roleId : roleIdsSplit) {
                List<Menu> menus = kingKongDistrictRepository.findAppMenuMoreByParkId(Long.valueOf(roleId), parkId, "2");
                menuList = takeUnion(menuList, menus);
            }
        }
        return setChildren(menuList);
    }

    //设置子集
    private List<Menu> setChildren(List<Menu> menuList) {
        if (CollectionUtils.isNotEmpty(menuList)) {
            for (Menu parentMenu : menuList) {
                for (Menu childrenMenu : menuList) {
                    if (childrenMenu.getParentId() != null &&
                            parentMenu.getId().equals(childrenMenu.getParentId())) {
                        if (CollectionUtils.isEmpty(parentMenu.getChildren())) {
                            ArrayList<Menu> menus = new ArrayList<>();
                            menus.add(childrenMenu);
                            parentMenu.setChildren(menus);
                        } else {
                            parentMenu.getChildren().add(childrenMenu);
                        }
                    }
                }
            }
        }
        menuList.removeIf(menu -> menu.getParentId() != null);
        return menuList;
    }

    /**
     * 取权限的去重并集
     * @param menuIterable
     * @param newMenuIterable
     * @return
     */
    private List<Menu> takeUnion(List<Menu> menuIterable, List<Menu> newMenuIterable) {
        List<Menu> menuList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(menuIterable) && CollectionUtils.isNotEmpty(newMenuIterable)) {
            menuList.addAll(menuIterable);
            menuList.addAll(newMenuIterable);
            menuList = menuList.stream().distinct().collect(toList());
        } else if (CollectionUtils.isEmpty(menuIterable) && CollectionUtils.isNotEmpty(newMenuIterable)) {
            menuList = newMenuIterable;
        } else {
            menuList = menuIterable;
        }
        return menuList;
    }
}
